package com.ljh.localmusic.foundation.media_player

import androidx.media3.common.MediaItem
import androidx.media3.common.Player
import androidx.media3.exoplayer.ExoPlayer
import com.ljh.localmusic.utils.MediaStateEvents
import com.ljh.localmusic.utils.MusicStates
import com.ljh.localmusic.utils.ext.logd
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
import javax.inject.Inject

/**
 * author：LJH on 2025/8/15 16:56
 *
 */
class MusicServiceHandler @Inject constructor(
    private val exoplayer: Player
) :Player.Listener{

    private val _musicStates = MutableStateFlow<MusicStates>(MusicStates.Initial)
    val musicStates = _musicStates.asStateFlow()

    private var job: Job? = null
    private val scope by lazy {
        CoroutineScope(Dispatchers.Main)
    }

    fun currentItemIndex(): Int {
        return exoplayer.currentMediaItemIndex
    }

    init {
        exoplayer.addListener(this)
    }

    fun setMediaItem(mediaItem: MediaItem){
        exoplayer.setMediaItem(mediaItem)
        exoplayer.prepare()
    }

    fun setMediaItem(mediaItems: List<MediaItem>){
        exoplayer.setMediaItems(mediaItems)
//        exoplayer.repeatMode = ExoPlayer.REPEAT_MODE_OFF
        exoplayer.prepare()
    }

    fun onMediaStateEvent(
        mediaStateEvent:MediaStateEvents,
        selectMusicIndex: Int = -1,
        seekPosition: Long = 0
    ){
        "onMediaStateEvent: $mediaStateEvent".logd()
        when(mediaStateEvent){
            is MediaStateEvents.PlayPause -> playPauseMusic()
            is MediaStateEvents.SeekTo -> exoplayer.seekTo(seekPosition)
            is MediaStateEvents.SeekToNext -> exoplayer.seekToNext()
            is MediaStateEvents.SeekToPrevious -> exoplayer.seekToPrevious()
            is MediaStateEvents.Stop -> exoplayer.stop()
            is MediaStateEvents.Release -> {
                try {
                    exoplayer.removeListener(this)
                    exoplayer.release()
                } catch (e: Exception){
                    e.printStackTrace()
                }
            }
            is MediaStateEvents.Backward -> exoplayer.seekBack()
            is MediaStateEvents.Forward -> exoplayer.seekForward()
            is MediaStateEvents.SelectedMusicChange -> {
                when(selectMusicIndex){
                    exoplayer.currentMediaItemIndex -> {
                        "索引变了...".logd()
                        if (!exoplayer.isPlaying){
                            playPauseMusic()
                        }
                    }
                    else -> {
                        exoplayer.seekToDefaultPosition(selectMusicIndex)
                        _musicStates.value = MusicStates.MediaPlaying(isPlaying = true)
                        exoplayer.playWhenReady = true
                        startProgressUpdate()
                    }
                }
            }
            is MediaStateEvents.MediaProgress -> {
                exoplayer.seekTo((exoplayer.duration * mediaStateEvent.progress).toLong())
            }
        }
    }

    override fun onPlaybackStateChanged(playbackState: Int) {
        "播放状态 ---> $playbackState".logd()
        when(playbackState){
            ExoPlayer.STATE_BUFFERING -> _musicStates.value = MusicStates.MediaBuffering(exoplayer.currentPosition)
            ExoPlayer.STATE_READY -> _musicStates.value = MusicStates.MediaReady(exoplayer.duration)
            ExoPlayer.STATE_ENDED -> {
                "列表播放结束了".logd()
            }
            ExoPlayer.STATE_IDLE -> {}
        }
    }

    override fun onIsPlayingChanged(isPlaying: Boolean) {
        "索引切换了！！ ---> ${exoplayer.currentMediaItemIndex}".logd()
        _musicStates.value = MusicStates.MediaPlaying(isPlaying)
        _musicStates.value = MusicStates.CurrentMediaItemIndex(exoplayer.currentMediaItemIndex)
        if (isPlaying){
            startProgressUpdate()
        } else {
            stopProgressUpdate()
        }
    }

    private fun playPauseMusic(){
        if (exoplayer.isPlaying){
            exoplayer.pause()
            stopProgressUpdate()
        } else {
            exoplayer.play()
            _musicStates.value = MusicStates.MediaPlaying(isPlaying = true)
            startProgressUpdate()
        }
    }

    override fun onMediaItemTransition(
        mediaItem: MediaItem?,
        reason: Int
    ) {
        // 当播放器切换到播放列表中的新媒体项时调用此方法
        // mediaItem 为当前切换到的新媒体项，reason 为切换的原因
        super.onMediaItemTransition(mediaItem, reason);
        if (reason == Player.MEDIA_ITEM_TRANSITION_REASON_AUTO) {
            // 这里表示是自动切换到下一首
            // 可以在这里添加你需要的逻辑，比如打印日志、更新UI等
            "ExoPlayer自动切换到下一首了,current: ${exoplayer.currentMediaItemIndex}".logd()
//            exoplayer.pause()
            _musicStates.value = MusicStates.AutoChangeMediaItem(exoplayer.currentMediaItemIndex)
        }
    }

    private fun startProgressUpdate() {
        job?.cancel()
        job = scope.launch{
            while (true){
                delay(500)
                _musicStates.value = MusicStates.MediaProgress(exoplayer.currentPosition)
            }
        }
    }

    private fun stopProgressUpdate(){
        job?.cancel()
        job = null
        _musicStates.value = MusicStates.MediaPlaying(isPlaying = false)
    }

}